/*
 * bsp_rf.c
 *
 *  Created on: 2023年7月4日
 *      Author: zlw
 */

#include <rail_config.h>
#include "bsp_rf.h"
#include "pa_conversions_efr32.h"
#include "app_log.h"
#include "mac_transmitter.h"
#include "mac_receiver.h"
#include "mac_timeSync.h"
#include "mac_fhss.h"
#include "softwareMultiTimer.h"
#include "app_cli_cmd.h"
#include "device.h"
#include "em_emu.h"
#include "bsp_gpio.h"
#include "mac_packetHandle.h"

#define SIZEOF_UINT32_DELTA_SUBTRACT 4
#define SIZEOF_UINT32_DELTA_ADD_0    4
#define SIZEOF_UINT32_DELTA_ADD_1    4

 #define CHANNEL_HOPPING_BUFFER_SIZE (        \
   3 +                                          \
   (RAIL_CHANNEL_HOPPING_BUFFER_SIZE_PER_CHANNEL * RF_HOP_CHAN_NUM_DEFAULT) +   \
   2 * (SIZEOF_UINT32_DELTA_SUBTRACT + SIZEOF_UINT32_DELTA_ADD_0 +SIZEOF_UINT32_DELTA_ADD_1 ) \
)

static RAIL_Handle_t railHandler = NULL;
static RF_PACKET_ST  s_stRfPacket; //ToDo 增加多接收报文的缓存能力，可malloc获得
static MAC_RF_STATE_E s_rfState = EN_MAC_RF_STATE_IDLE;

//
static uint32_t chanHopConfigBuff[CHANNEL_HOPPING_BUFFER_SIZE];//   * @note the size of this buffer must be at least as large as  3 + 30 * numberOfChannels, plus the sum of the sizes of the

static RAIL_RxChannelHoppingConfigMultiMode_t  resyncChanConfigMultiMode =
    {
        .timingSense = 1042, //  40bit
        .timingReSense= 4557,//3125,
        .preambleSense= 4557,//3125,   //135bit前导码 + timingSense = 175bit
        .syncDetect=   8489//5890  //135bit+16bit报文前导同步长度 + preambleSense = 326bit
    };
static RAIL_RxChannelHoppingConfigMultiMode_t  mainChanConfigMultiMode =
    {
        .timingSense = 1042,//40bit
        .timingReSense= 4557,
        .preambleSense= 4557,   //135bit前导码 + timingSense = 175bit
        .syncDetect=   8489  //135bit+16bit报文前导同步长度 + preambleSense = 326bit，主信道长点
    };


static RAIL_RxChannelHoppingConfigEntry_t channelHoppingEntries[RF_HOP_CHAN_NUM_DEFAULT] =
{
    {
        .channel = RF_CHAN_RESYNC_DEFAULT_NUMBER,// 备用信道
#ifdef HUB_DEVICE //HUB一般带天线分集
        .mode = RAIL_RX_CHANNEL_HOPPING_MODE_MULTI_SENSE,//多超时条件混合跳频，适用于天线分集场景
        .parameter = (uint32_t)(void *)&resyncChanConfigMultiMode,//备用信道配置
#else
        .mode = RAIL_RX_CHANNEL_HOPPING_MODE_TIMING_SENSE,//timing检测超时跳频
        .parameter = 660, // 单位us, 80bit前导码 共2083us
#endif
        .delay = 0,
        .delayMode = RAIL_RX_CHANNEL_HOPPING_DELAY_MODE_STATIC,
    },
    {
        .channel = RF_CHAN_NO_HOP_FIXED_UNMBER,// 主信道,偏移更多
#ifdef HUB_DEVICE //HUB一般带天线分集
        .mode = RAIL_RX_CHANNEL_HOPPING_MODE_MULTI_SENSE,//多超时条件混合跳频，适用于天线分集场景
        .parameter =(uint32_t)(void *)&mainChanConfigMultiMode, //主信道配置
#else
        .mode = RAIL_RX_CHANNEL_HOPPING_MODE_TIMING_SENSE,//timing检测超时跳频
        .parameter = 1000, // 单位us
#endif
        .delay = 0,
        .delayMode = RAIL_RX_CHANNEL_HOPPING_DELAY_MODE_STATIC,
    }
};

static RAIL_RxChannelHoppingConfig_t s_stChanHopConfig =
{
    .buffer = chanHopConfigBuff,
    .bufferLength = CHANNEL_HOPPING_BUFFER_SIZE,
    .numberOfChannels = RF_HOP_CHAN_NUM_DEFAULT,
    .entries = channelHoppingEntries,
};

void bsp_rail_util_pa_init(void)
{
  (void)RAIL_InitTxPowerCurvesAlt(&RAIL_TxPowerCurvesVbat);
  RAIL_EnablePaCal(true);
}

void bsp_rail_util_rssi_init(void)
{
  (void)RAIL_SetRssiOffset(RAIL_EFR32_HANDLE, (int8_t)0);
}

/***************************rf init*************************************/

static __ALIGNED(RAIL_FIFO_ALIGNMENT) uint8_t ds_tx_fifo[DS_FLEX_RAIL_TX_FIFO_SIZE];
static __ALIGNED(RAIL_FIFO_ALIGNMENT) uint8_t ds_rx_fifo[DS_FLEX_RAIL_RX_FIFO_SIZE];

static RAIL_TxPowerConfig_t dsTxPowerConfigSubGhz = {
  .mode = RAIL_TX_POWER_MODE_SUBGIG_HIGHEST,
  .voltage = 3300,//1800,//3300,  //PA供电3300V 20dbm匹配网络 与1800V 14dbm匹配网络
  .rampTime = 10,
};

static uint16_t unpack_packet(uint8_t *rx_destination, const RAIL_RxPacketInfo_t *packet_information, uint8_t **start_of_payload)
{
  RAIL_CopyRxPacket(rx_destination, packet_information);
  *start_of_payload = rx_destination;
  //DS_app_log_info("Package is ready, %d bytes read\n", packet_information->packetBytes);

  return packet_information->packetBytes;
}

void rxCompleteHandle(void *pFun, uint8_t state, void* pData)
{
  RAIL_RxPacketHandle_t rx_packet_handle;
  RAIL_Status_t rail_status = RAIL_STATUS_NO_ERROR;
  RAIL_RxPacketInfo_t packet_info;
  RAIL_Handle_t rail_handle = railHandler;
  PFUNC_RX_CALLBACK pCallback = (PFUNC_RX_CALLBACK) pFun;

  rx_packet_handle = RAIL_GetRxPacketInfo(rail_handle, RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE, &packet_info);
  rail_status = RAIL_GetRxPacketDetails(rail_handle, rx_packet_handle, &(s_stRfPacket.details));

  while (rx_packet_handle != RAIL_RX_PACKET_HANDLE_INVALID) {
    s_stRfPacket.packet_size = unpack_packet(ds_rx_fifo, &packet_info, &(s_stRfPacket.start_of_packet));
    rail_status = RAIL_ReleaseRxPacket(rail_handle, rx_packet_handle);

    //ToDo 将读fifo，取packet 放入到mac_receiver状态机内处理
    if(pCallback != NULL)
    {
        pCallback(&s_stRfPacket,state,pData);
    }
    rx_packet_handle = RAIL_GetRxPacketInfo(rail_handle, RAIL_RX_PACKET_HANDLE_OLDEST_COMPLETE, &packet_info);
    if(get_mac_printf_log())
      printf(":%d",rail_status);
  }

  RAIL_ResetFifo(rail_handle, false, true);
}

RF_PACKET_ST* getLastRecvPacketPoint()
 {
   return (&s_stRfPacket);
 }

//该终端处理函数调用Rail库，栈空间消耗尚不明确
static void railUntilOnEventHandler(RAIL_Handle_t rail_handle, RAIL_Events_t events)
{
  // Handle Rx events
  if ( events & RAIL_EVENTS_RX_COMPLETION ) {
    if (events & RAIL_EVENT_RX_PACKET_RECEIVED) {

        setRxTimeStamp(READ_BU_RTC_COUNT());
      // Keep the packet in the radio buffer, download it later at the state machine
        RAIL_HoldRxPacket(rail_handle);
        //ToDo 增加缓存，或互斥（当该值未被取走消费时getMacRxStateEvent，停止更新或报错），防止后台来不及处理报文导致该值被覆盖，

        setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,true); //ToDo 不管Rx状态机处于什么状态，均处理该事件.
        printf("@");
    }
    else if (events & RAIL_EVENT_RX_FRAME_ERROR) {
        setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,false);
//        RAIL_RxPacketInfo_t packet_info; //转到该块内声明和定义局部变量，减少中断服务对栈的压力，仅供RF事件中断调试用，可删除之，避免影响栈和正常功能
//        RAIL_GetRxPacketInfo(rail_handle, RAIL_RX_PACKET_HANDLE_NEWEST, &packet_info);
//        RAIL_RxPacketDetails_t packet_details;
//        RAIL_GetRxPacketDetails(rail_handle, RAIL_RX_PACKET_HANDLE_NEWEST, &packet_details);
//        printf("$%d,A%d,C%d,%d",packet_details.crcPassed,packet_details.antennaId,packet_details.channel,packet_details.rssi);
        printf("$");
    }

    else if(events & RAIL_EVENT_RX_FIFO_OVERFLOW){
        setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,true); //ToDo test 接收buffer溢出后，必须想办法处理.
        printf("^");
    }

    else{
        printf("?");
        setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PAYLOAD_DONE,false);
    }

  }

  // Handle Tx event
  if ( events & RAIL_EVENTS_TX_COMPLETION) {
      if(events & RAIL_EVENT_TX_PACKET_SENT){
        setMacTxStateEvent(EN_MAC_TX_EVENT_TYPE_SEND_DONE,true); //bug，ToDo 是否发送成功，如果接收报文的同时发送，是否发送失败？？
        printf("&");
      }
      else
        {
          printf("|");
        }
  }

  //仅测试用
  if(events & RAIL_EVENT_RX_TIMING_DETECT) {

      printf("v");
  }
  if(events & RAIL_EVENT_RX_TIMING_LOST) {

      printf("k");
  }

  //ToDo 可考虑关闭取消同步字检测事件，保留前导码检测事件
  if(events & RAIL_EVENT_RX_PREAMBLE_DETECT) {
      setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE,true);
      if(get_mac_printf_log())
        printf("~");
  }

  if(events & RAIL_EVENT_RX_PREAMBLE_LOST)
  {
      if(get_mac_printf_log())
        printf("\\");
  }

  if(events & (RAIL_EVENT_RX_SYNC1_DETECT | RAIL_EVENT_RX_SYNC2_DETECT)) {
#ifdef RX_EVENT_TYPE_RF_SYNC_DONE_ENABLED
      setMacRxStateEvent(EN_MAC_RX_EVENT_TYPE_RF_SYNC_DONE,true);
#endif
      s_stRfPacket.AfcError = RAIL_GetRxFreqOffset(rail_handle);
      if(get_mac_printf_log())
        printf("!");
  }

}

static void rfReadyEventHandler(RAIL_Handle_t rail_handle)
{
  (void)rail_handle;
}

static void ds_rail_util_pa_on_channel_config_change_handler(RAIL_Handle_t rail_handle,
                                              const RAIL_ChannelConfigEntry_t *entry)
{
  RAIL_Status_t status;
  if (!RAIL_IsPaAutoModeEnabled(rail_handle)) {
    RAIL_TxPowerConfig_t currentTxPowerConfig;
    RAIL_TxPowerConfig_t *newTxPowerConfigPtr;

    // Get current TX Power Config.
    status = RAIL_GetTxPowerConfig(rail_handle, &currentTxPowerConfig);
    if (status != RAIL_STATUS_NO_ERROR) {
        DS_app_log_error("get TxPower Config error, status = 0x%x\r\n", status);
    }

    (void) entry;

    newTxPowerConfigPtr = &dsTxPowerConfigSubGhz;

    // Call RAIL_ConfigTxPower only if TX Power Config mode has changed.
    if (currentTxPowerConfig.mode != newTxPowerConfigPtr->mode) {
      // Save current TX power before RAIL_ConfigTxPower (because not preserved).
      RAIL_TxPower_t txPowerDeciDbm;
      if (currentTxPowerConfig.mode == RAIL_TX_POWER_MODE_NONE) {
          int ret = getThisParam(RfTxPower, &txPowerDeciDbm);
          if(ret != 0)
            txPowerDeciDbm = DS_RAIL_UTIL_PA_POWER_DECI_DBM; //200即20dbm 最大，目前默认10dbm
      } else {
        txPowerDeciDbm = RAIL_GetTxPowerDbm(rail_handle);
      }
      // Apply new TX Power Config.
      status = RAIL_ConfigTxPower(rail_handle, newTxPowerConfigPtr);
      if(RAIL_STATUS_NO_ERROR == status){
          status = RAIL_GetTxPowerConfig(rail_handle, &currentTxPowerConfig);//获取当前的配置，并更新之
          if(RAIL_STATUS_NO_ERROR == status){
              printf("newTxMode:%d-",newTxPowerConfigPtr->mode);
              newTxPowerConfigPtr->mode = currentTxPowerConfig.mode;
              printf("%d\r\n",newTxPowerConfigPtr->mode);
          }
      }

      // Restore TX power after RAIL_ConfigTxPower.
      status = bsp_rf_set_tx_power_bdm(txPowerDeciDbm); // status = RAIL_SetTxPowerDbm(rail_handle, txPowerDeciDbm);
      //if(get_mac_printf_log())
      printf("TP:%d %d M%d\r\n",status,bsp_rf_get_tx_power_bdm(),currentTxPowerConfig.mode);
    }
  } // !RAIL_IsPaAutoModeEnabled
}

static void channelConfigChangehandler(RAIL_Handle_t rail_handle, const RAIL_ChannelConfigEntry_t *entry)
{
  ds_rail_util_pa_on_channel_config_change_handler(rail_handle, entry);
}

static void bsp_rf_init(railUntilOnEventCallback railuntilOnEventHandler,
                          rfReadyCallback rfReadyHandler,
                          channelConfigChangeCallback channelCofigChangeHandler)
{
  RAIL_Status_t status;
  RAIL_Config_t sl_rail_config = {
      .eventsCallback = railuntilOnEventHandler,
  };

  railHandler = RAIL_Init(&sl_rail_config, rfReadyHandler);

  RAIL_DataConfig_t data_config = {
    .txSource = TX_PACKET_DATA,
    .rxSource = RX_PACKET_DATA,
    .txMethod = PACKET_MODE,//FIFO_MODE
    .rxMethod = PACKET_MODE,//FIFO_MODE
  };
  status = RAIL_ConfigData(railHandler, &data_config);
  if(RAIL_STATUS_NO_ERROR != status) {
      DS_app_log_error("rail config data failed \r\n");
  }

  const RAIL_ChannelConfig_t *channel_config = channelConfigs[getDeviceRfFreq()];
  (void) RAIL_ConfigChannels(railHandler, channel_config, channelCofigChangeHandler);
  /*status = RAIL_SetPtiProtocol(railHandler, RAIL_PTI_PROTOCOL_CUSTOM);
  if(RAIL_STATUS_NO_ERROR != status) {
      DS_app_log_error("rail set pti protocol failed \r\n");
  }*/

  status = RAIL_ConfigCal(railHandler,
                          0U
                          | (1
                             ? RAIL_CAL_TEMP : 0U)
                          | (1
                             ? RAIL_CAL_ONETIME : 0U));
  if(RAIL_STATUS_NO_ERROR != status) {
      DS_app_log_error("rail config calibration failed \r\n");
  }

  status = RAIL_ConfigEvents(railHandler, RAIL_EVENTS_ALL, DS_RAIL_UTIL_INIT_EVENT_INST0_MASK);
  if(RAIL_STATUS_NO_ERROR != status) {
      DS_app_log_error("rail config event failed \r\n");
  }
}
//TODO，若在运行过程中，因RAIL收发异常想重新初始化RAIL库 仅调用该函数无效，会出现接收异常的问题
void bsp_rf_config_chan()
{
  const RAIL_ChannelConfig_t *channel_config = channelConfigs[getDeviceRfFreq()];
  (void) RAIL_ConfigChannels(railHandler, channel_config, &channelConfigChangehandler);
}

void rf_init(void)
{
  bsp_rail_util_pa_init();
  bsp_rail_util_rssi_init();
  bsp_rf_init(&railUntilOnEventHandler, &rfReadyEventHandler, &channelConfigChangehandler);
  //ToDo 根据角色初始化 状态转移
  bsp_rf_tx_transition_set(RAIL_RF_STATE_IDLE, RAIL_RF_STATE_IDLE);//ToDo HUB角色 发送接收完成后可自动开启接收
  bsp_rf_rx_transition_set(RAIL_RF_STATE_IDLE, RAIL_RF_STATE_IDLE); //ToDo HUB角色 接收完成后可自动开启接收
  bsp_set_up_tx_fifo(ds_tx_fifo, DS_FLEX_RAIL_TX_FIFO_SIZE);
  bsp_set_up_rx_fifo(ds_rx_fifo, DS_FLEX_RAIL_RX_FIFO_SIZE);//ToDo  RxFiFo size加大
  //RAIL_ConfigSleep(railHandler, RAIL_SLEEP_CONFIG_TIMERSYNC_DISABLED); //休眠时不使能定时器

  if(bsp_rf_antenna_diversity_feature_get()) {
      RAIL_AntennaConfig_t config = {
          .ant0PinEn = 1,
          .ant1PinEn = 0,
          .defaultPath = RAIL_ANTENNA_0,
          .reserved = 0,
          .ant0Port = ANT0_PORT,
          .ant0Pin = ANT0_PIN,
          .ant1Port = 0,
          .ant1Pin = 0
      };
      uint8_t ret;
      ret = bsp_rf_config_antenna(&config);//TODO 240306 存在重启后，天线分集配置未生效的情况，怀疑是rf不处于idle的情况，此处需强制切换
      if(ret != RAIL_STATUS_NO_ERROR){
          printf("rf config fail%d",ret);
          bsp_set_rf_idle(RAIL_IDLE_ABORT, true);
          ret = bsp_rf_config_antenna(&config);
          printf("-re%d\r\n",ret);
      }
      //当天线分集使能时，Hop 配置为MultiMode
      channelHoppingEntries[0].mode = RAIL_RX_CHANNEL_HOPPING_MODE_MULTI_SENSE;//多超时条件混合跳频，适用于天线分集场景
      channelHoppingEntries[0].parameter =  (uint32_t)(void *)&resyncChanConfigMultiMode; //混合模式备用信道配置
      channelHoppingEntries[1].mode = RAIL_RX_CHANNEL_HOPPING_MODE_MULTI_SENSE;//多超时条件混合跳频，适用于天线分集场景
      channelHoppingEntries[1].parameter =  (uint32_t)(void *)&mainChanConfigMultiMode; //混合模式主信道配置
  }
  else
  {
    //无天线分集功能时，使用默认的timingsens来跳频
    channelHoppingEntries[0].mode =  RAIL_RX_CHANNEL_HOPPING_MODE_TIMING_SENSE;//timing检测超时跳频
    channelHoppingEntries[0].parameter = 660; // 单位us, 80bit前导码 共2083us
    channelHoppingEntries[1].mode = RAIL_RX_CHANNEL_HOPPING_MODE_TIMING_SENSE;//timing检测超时跳频
    channelHoppingEntries[1].parameter = 1000;// 单位us
  }
}

int16_t bsp_rf_get_raw_rssi(bool isWait)
{
  int16_t rssi = RAIL_GetRssi(railHandler,false);//非阻塞读取Rssi
  if(isWait)
  {
     uint32_t currentRtc = READ_SYS_RTC_COUNT();
     //超时阻塞等待读到合法Rssi
     while(rssi == RAIL_RSSI_INVALID)
     {
        if(getRfState() != EN_MAC_RF_STATE_WAIT_PREAMBLE)//实时获取RF芯片的状态，不处于等待前导码状态则提前退出
        {
          printf("[ERR] getRssi state%d\r\n",getRfState());
          break;
        }
        if(READ_SYS_RTC_COUNT() - currentRtc > LISTEN_BACKRSSI_WINDOW_TIMEOUT)
        {
          printf("[ERR] getRssi timeout\r\n");
          break;
        }
        rssi = RAIL_GetRssi(railHandler,false);//非阻塞读取Rssi，重复轮询读取，直至超时
     }
  }
  return rssi;
}
/****************************************************************/

void bsp_set_rf_idle(RAIL_IdleMode_t mode, bool wait) //超时100ms，即报文最长不超过100ms
{
  //RAIL_Idle(railHandler, RAIL_IDLE_FORCE_SHUTDOWN, false); // for test!!!!!!!!!! 需删除
  RAIL_Idle(railHandler, mode, false);
  //如果阻塞等待idle完成，
  if(wait)
  {
    uint32_t currentRtc = READ_SYS_RTC_COUNT();
    while(getRfState() != EN_MAC_RF_STATE_IDLE)//若获取的状态不等于Idle，则等待并重复调用进入idle函数
    {
       RAIL_Idle(railHandler, mode, false);
       if(READ_SYS_RTC_COUNT() - currentRtc > 6553) //异常处理，1最严重 阻塞超过200ms，shutdown失败，退出
       {
         printf("[ERR] rf shutDown fail \r\n");
         break;//退出，实际上应该直接重启
       }
       else if(READ_SYS_RTC_COUNT() - currentRtc > 3276)//异常处理 2 阻塞超过100ms，调用shutdown
       {
         if(mode != RAIL_IDLE_FORCE_SHUTDOWN)
          {
            mode = RAIL_IDLE_FORCE_SHUTDOWN; //idle失败，直接shutdow
            printf("[ERR] rf idle fail\r\n");
          }
       }
    }
  }
}

uint8_t bsp_get_rf_state(void)
{
  return RAIL_GetRadioState(railHandler);
}

MAC_RF_STATE_E getRfState(void)
{
  RAIL_RadioState_t state = bsp_get_rf_state();
  if (state == RAIL_RF_STATE_IDLE)
  {
      s_rfState = EN_MAC_RF_STATE_IDLE;
  }
  else if(state == RAIL_RF_STATE_RX_ACTIVE)
  {
      s_rfState = EN_MAC_RF_STATE_RX_PAYLOADING;
  }
  else if(state == RAIL_RF_STATE_TX_ACTIVE || state == RAIL_RF_STATE_TX)
  {
      s_rfState = EN_MAC_RF_STATE_TX_PAYLOADING;
  }
  //0814 收到前导码中断亦认为是RX PAYLOADING态，阻止发送打断，ToDo Debug，若RF PREAMBLE在 非法RX状态内被置位，是否存在无法被清除的情况，增加保护，确保EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE可被清除
  else if(state == RAIL_RF_STATE_RX && getMacRxStateEventType(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE) && getMacRxStateEventValue(EN_MAC_RX_EVENT_TYPE_RF_PREAMBLE_DONE))
  {
      s_rfState = EN_MAC_RF_STATE_RX_PAYLOADING;
  }
  else if(state == RAIL_RF_STATE_RX)
  {
      s_rfState = EN_MAC_RF_STATE_WAIT_PREAMBLE;
  }
  else if(state == RAIL_RF_STATE_INACTIVE)
  {
      s_rfState = EN_MAC_RF_STATE_IDLE;
  }
  else
  {
      s_rfState = EN_MAC_RF_STATE_IDLE;
      printf("RE 0x%x\r\n",state);
  }
  return s_rfState;
}

uint8_t bsp_rf_set_tx_preambleLen(uint16_t Len)
{
  return RAIL_SetTxAltPreambleLength(railHandler,Len);
}

uint8_t bsp_rf_set_tx_power_bdm(RAIL_TxPower_t power)
{
  RAIL_TxPower_t set_power = power;
  if(getDeviceRfFreq() == RF_FREQ_868MHZ_WPC){
      if(set_power > WPC_MAX_POWER_DECI_DBM){
          printf("set tp %d out, use max tp %d\r\n",set_power, WPC_MAX_POWER_DECI_DBM);
          set_power = WPC_MAX_POWER_DECI_DBM;
      }
  }
  return RAIL_SetTxPowerDbm(railHandler, set_power);
}

int16_t bsp_rf_get_tx_power_bdm(void)
{
  return RAIL_GetTxPowerDbm(railHandler);
}

uint8_t bsp_rf_is_channel_valid(uint16_t channel)
{
  return RAIL_IsValidChannel(railHandler, channel);
}

uint8_t bsp_rf_set_channel(uint32_t channel)
{
  if (((bsp_get_rf_state() & RAIL_RF_STATE_RX) != 0U)) {
    return RAIL_StartRx(railHandler, channel, NULL);
  } else {
    return RAIL_PrepareChannel(railHandler, channel);
  }
}

uint8_t bsp_rf_get_channel(uint16_t *channel)
{
  return RAIL_GetChannel(railHandler, channel);
}

uint8_t bsp_rf_start_tx(uint16_t channel, RAIL_TxOptions_t options, const RAIL_SchedulerInfo_t *schedulerInfo)
{
  return RAIL_StartTx(railHandler, channel, options, schedulerInfo);
}

//uint8_t bsp_rf_start_ccaLbt_tx(uint16_t channel, RAIL_TxOptions_t options,  const RAIL_LbtConfig_t *lbtConfig, const RAIL_SchedulerInfo_t *schedulerInfo)
//{
//  return RAIL_StartCcaLbtTx(railHandler, channel, options, lbtConfig, schedulerInfo);
//}
//
//uint8_t bsp_rf_start_ccaLbt_schedule_tx(uint16_t channel, RAIL_TxOptions_t options, const RAIL_ScheduleTxConfig_t *scheduleTxConfig, const RAIL_LbtConfig_t *lbtConfig, const RAIL_SchedulerInfo_t *schedulerInfo)
//{
//  return RAIL_StartScheduledCcaLbtTx(railHandler, channel, options, scheduleTxConfig,lbtConfig, schedulerInfo);
//}

uint8_t bsp_rf_start_tx_stream_alt(uint16_t channel, RAIL_StreamMode_t mode, RAIL_TxOptions_t options)
{
  return RAIL_StartTxStreamAlt(railHandler, channel, mode, options);
}

uint8_t bsp_rf_stop_tx_stream(void)
{
  return RAIL_StopTxStream(railHandler);
}

uint8_t bsp_rf_config_rx_option(RAIL_RxOptions_t mask,RAIL_RxOptions_t options)
{
  return RAIL_ConfigRxOptions(railHandler,mask,options);
}

uint8_t bsp_rf_start_rx(uint16_t channel, const RAIL_SchedulerInfo_t *schedulerInfo)
{
  return RAIL_StartRx(railHandler,channel,schedulerInfo);
}

uint16_t bsp_set_up_tx_fifo(uint8_t *fifo, uint16_t fifo_size)
{
  return RAIL_SetTxFifo(railHandler, fifo, 0, fifo_size);
}

uint16_t bsp_set_up_rx_fifo(uint8_t *fifo, uint16_t fifo_size)
{
  return RAIL_SetRxFifo(railHandler, fifo, &fifo_size);
}

DS_STATUS_ENUM bsp_rf_set_ctune(uint32_t ctune)
{
  return RAIL_SetTune(railHandler, ctune);
}

uint32_t bsp_rf_get_ctune(void)
{
  return RAIL_GetTune(railHandler);
}

void bsp_rf_reset_fifo(bool txFifo, bool rxFifo)
{
  RAIL_ResetFifo(railHandler, txFifo, rxFifo);
}

uint16_t bsp_rf_write_tx_fifo(const uint8_t *dataPtr, uint16_t writeLength, bool reset)
{
  return RAIL_WriteTxFifo(railHandler, dataPtr, writeLength, reset);
}

uint8_t bsp_rf_rx_channel_hopping_enable(bool enable, bool reset)
{
  if(channelHoppingEntries[0].channel == channelHoppingEntries[1].channel )
  {
    if(get_mac_printf_log())
      printf("="); //Todo，可失能跳频
    enable = false;
  }
  bsp_set_rf_idle(RAIL_IDLE_ABORT, true); //需先处于Idle再进行接收，已经是false 再 false是否报错？
  return RAIL_EnableRxChannelHopping(railHandler, enable, reset);
}

uint8_t bsp_rf_set_hop_main_chan(uint8_t mainChan)
{
  uint8_t temp8;
  uint8_t ret;
  temp8 = channelHoppingEntries[1].channel;
  channelHoppingEntries[1].channel = mainChan;
  bsp_set_rf_idle(RAIL_IDLE_ABORT, true); //需先处于Idle再进行相关 跳频Hop配置
  bsp_rf_rx_channel_hopping_enable(false,false);// 跳频Hop失能 再进行修改配置
  ret = RAIL_ConfigRxChannelHopping(railHandler, &s_stChanHopConfig);
  if(ret != RAIL_STATUS_NO_ERROR)
  {
     channelHoppingEntries[1].channel = temp8; //若配置失败 则恢复之前的channel
  }
  return ret;
}
//获取跳频主、备用信道的背景噪声rssi
int16_t bsp_rf_get_hop_main_chan_rssi()
{
  return RAIL_GetChannelHoppingRssi(railHandler,1);
}

int16_t bsp_rf_get_hop_resync_chan_rssi()
{
  return RAIL_GetChannelHoppingRssi(railHandler,0);
}

uint8_t bsp_rf_get_hop_main_chan()
{
  return channelHoppingEntries[1].channel;
}

void bsp_rf_cw(uint8_t chan)
{
  bsp_set_rf_idle(RAIL_IDLE_ABORT, true); //需先处于Idle再进行接收，已经是false 再 false是否报错？
  uint8_t ret = RAIL_StartTxStream(railHandler, chan, RAIL_STREAM_CARRIER_WAVE);
  //printf("cw ret%d\r\n",ret);
}

//ToDo 注意 resync Chan 将跟随 mainChan更新时配置下去,最大400ms延时？
uint8_t bsp_rf_set_hop_resync_chan(uint8_t resyncChan)
{
  channelHoppingEntries[0].channel = resyncChan;
  return 0;
}

uint8_t bsp_rf_get_hop_resync_chan()
{
  return channelHoppingEntries[0].channel;
}

uint8_t bsp_rf_tx_transition_set(RAIL_RadioState_t successState, RAIL_RadioState_t errorState)
{
  RAIL_StateTransitions_t tx_transitions = {
    .success = successState,
    .error = errorState
  };
  return RAIL_SetTxTransitions(railHandler, &tx_transitions);
}

uint8_t bsp_rf_rx_transition_set(RAIL_RadioState_t successState, RAIL_RadioState_t errorState)
{
  RAIL_StateTransitions_t rx_transitions = {
    .success = successState,
    .error = errorState
  };
  return RAIL_SetRxTransitions(railHandler, &rx_transitions);
}

int8_t bsp_rf_rssi_get(void)
{
  return s_stRfPacket.details.rssi;
}

bool bsp_rf_antenna_diversity_feature_get(void)
{
#ifdef HUB_DEVICE
  return true;
#else
  return false;
#endif
}

uint8_t bsp_rf_config_antenna(const RAIL_AntennaConfig_t *config)
{
  return RAIL_ConfigAntenna(railHandler, config);
}

/**
 * brief:select antenna
 * param: 1:external 0:internal
 * */
void bsp_rf_antenna_select(uint8_t ante)
{
  ds_gpio_t annSelect = {
      .port = gpioPortA,
      .pin = 4,
      .mode = gpioModePushPull,
      .initial = 0,
      .valid = 1,
  };

  ds_gpio_init(&annSelect);
  if(ante) {
      ds_gpio_on(&annSelect);
  }
  else {
      ds_gpio_off(&annSelect);
  }
}

